package com.mcsyr.clearitem;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.Date;
import java.util.List;

public class tools {
    /**
     * 定时清理垃圾
     */
    public static void Scheduler() {
        if (Main.ClearItemTime > 0) {
            Bukkit.getScheduler().runTaskTimerAsynchronously(Main.plugin, () -> {
                ++Main.time;
                if (Main.ClearItemTime - Main.time == 60) {
                    Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClearPre.replace("%time%", "60"));
                } else if (Main.ClearItemTime - Main.time == 30) {
                    Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClearPre.replace("%time%", "30"));
                } else if (Main.ClearItemTime - Main.time == 10) {
                    Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClearPre.replace("%time%", "10"));
                } else if (Main.ClearItemTime - Main.time <= 0) {
                    Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClearStart);
                    //  记录第几次清理垃圾
                    ++Main.DustbinClearFrequency;
                    //  是否开启清理xx次垃圾后清空公共垃圾箱
                    if (Main.PublicDustbinEnable && Main.DustbinClearFrequency % Main.PublicDustbinClearInterval == 0) {
                        Dustbin.clearDustbin();
                        Bukkit.getServer().broadcastMessage(Main.PublicDustbinMessageClear);
                    }
                    tools.clearWorld();
                    Main.time = 0;
                }
                if(!Main.DropEnable) tools.CheckPlayerDropLock();
            }, 200L, 20L);
        }
    }

    /**
     * 检查在线玩家的丢弃物品锁
     * */
    public static void CheckPlayerDropLock() {
        long date = new Date().getTime();
        long playerDate;
        for (Player player : Bukkit.getServer().getOnlinePlayers()) {
            if (!Main.PlayerDropLock.get(player)) {
                playerDate = Main.PlayerDropLockTime.get(player).getTime();
                if (date - playerDate > Main.DropTime) {
                    Main.PlayerDropLock.put(player, true);
                    player.sendMessage(Main.DropMessageOpen);
                }
            }
        }
    }

    /**
     * 清理全部World的掉落物
     */
    public static void clearWorld() {
        int index = 0;
        List<World> worlds = Bukkit.getWorlds();
        int size = worlds.size();
        for (World world : worlds) {
            ++index;
            int finalIndex = index;
            Bukkit.getScheduler().runTaskLater(Main.plugin, () -> tools.clearWorldItem(world, finalIndex == size), 20L * index);
        }
    }

    /**
     * 清理指定World的掉落物
     *
     * @param world     需要清理的地图
     * @param isDustbin true表示最后一个地图，扫描完毕后统计垃圾箱新增数量
     */
    public static void clearWorldItem(World world, Boolean isDustbin) {
        int count = 0;// 统计垃圾数量
        int DustbinCount = 0;
        ItemStack itemStack;
        List<Entity> Entities = world.getEntities();
        List<String> lore;
        ItemMeta itemMeta;
        for (final Entity ent : Entities) {
            switch (ent.getType()) {
                case DROPPED_ITEM:
                    itemStack = ((Item) ent).getItemStack();
                    if (Main.ClearItemWhiteList.contains(itemStack.getType().name())) {
                        continue;
                    }
                    itemMeta = itemStack.getItemMeta();
                    if (itemMeta != null) {
                        if (Main.ClearItemWhiteListName.contains(itemMeta.getDisplayName())) {
                            continue;
                        }
                        lore = itemMeta.getLore();
                        if (lore != null) {
                            lore.retainAll(Main.ClearItemWhiteListLore);
                            if (!lore.isEmpty()) {
                                continue;
                            }
                        }
                    }
                    //  如果垃圾放进了公共垃圾箱则删除掉落物
                    Dustbin.addItem(itemStack);
                    ++DustbinCount;
                    ++count;
                    ent.remove();
                    continue;
                case ITEM_FRAME:
                    if (Main.ClearItemItemFrame) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case BOAT:
                    if (Main.ClearItemBoat) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case EXPERIENCE_ORB:
                    if (Main.ClearItemExpBall) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case FALLING_BLOCK:
                    if (Main.ClearItemFallingBlock) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case PAINTING:
                    if (Main.ClearItemPainting) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case MINECART:
                    if (Main.ClearItemMinecart) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case ARROW:
                    if (Main.ClearItemArrow) {
                        ++count;
                        ent.remove();
                    }
                    continue;
                case SNOWBALL:
                    if (Main.ClearItemSnowball) {
                        ++count;
                        ent.remove();
                    }
            }
        }
        Main.DustbinCount += DustbinCount;
        Main.WasteTotal += count;

        //  判断是分地图提示还是统计总和提示
        if (!Main.CleaningTipsEnable) {
            if (count > 0) {
                Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClearWorld
                        .replaceAll("%world%", tools.IncludeWorldAlias(world.getName()))
                        .replaceAll("%count%", String.valueOf(count))
                );
            }
        }

        //  判断是不是最后清理的那个世界
        if (isDustbin) {
            //  查询是否开启了公共垃圾箱
            if (Main.PublicDustbinEnable) {
                Bukkit.getServer().broadcastMessage(Main.PublicDustbinMessageReminder
                        .replace("%amount%", String.valueOf(Main.DustbinCount))
                );
            }
            // 如果为true则表示启动的是统计垃圾总和
            if (Main.CleaningTipsEnable) {
                Bukkit.getServer().broadcastMessage(Main.ClearItemMessageClear.replaceAll("%count%", String.valueOf(Main.WasteTotal)));
            }
            //  统计清零
            Main.DustbinCount = 0;
            Main.WasteTotal = 0;
        }
    }

    /**
     * 查询配置文件是否有当前世界的别名存在
     *
     * @param name 需要查询的世界名称
     * @return 返回查询并处理后的世界名称
     */
    public static String IncludeWorldAlias(String name) {
        if (Main.Config.getString("CleaningTips.WorldAlias." + name) == null) {
            return name;
        }
        return Main.Config.getString("CleaningTips.WorldAlias." + name);
    }

    /**
     * 清理该实体掉落物
     *
     * @param ent 需要删除的实体掉落物
     * @param lore 装载lore的List
     * @param itemMeta 保存ItemMeta
     */
    public static void clearEntityItem(Entity ent, List<String> lore, ItemMeta itemMeta) {
        switch (ent.getType()) {
            case DROPPED_ITEM:
                Item item = (Item) ent;
                if (Main.ClearItemWhiteList.contains(item.getItemStack().getType().name())) {
                    return;
                }
                itemMeta = item.getItemStack().getItemMeta();
                if (itemMeta != null) {
                    if (Main.ClearItemWhiteListName.contains(itemMeta.getDisplayName())) {
                        return;
                    }
                    lore = itemMeta.getLore();
                    if (lore != null) {
                        lore.retainAll(Main.ClearItemWhiteListLore);
                        if (!lore.isEmpty()) {
                            return;
                        }
                    }
                }
                ent.remove();
            case ITEM_FRAME:
                if (Main.ClearItemItemFrame) {
                    ent.remove();
                }
            case BOAT:
                if (Main.ClearItemBoat) {
                    ent.remove();
                }
            case EXPERIENCE_ORB:
                if (Main.ClearItemExpBall) {
                    ent.remove();
                }
            case FALLING_BLOCK:
                if (Main.ClearItemFallingBlock) {
                    ent.remove();
                }
            case PAINTING:
                if (Main.ClearItemPainting) {
                    ent.remove();
                }
            case MINECART:
                if (Main.ClearItemMinecart) {
                    ent.remove();
                }
            case ARROW:
                if (Main.ClearItemArrow) {
                    ent.remove();
                }
            case SNOWBALL:
                if (Main.ClearItemSnowball) {
                    ent.remove();
                }
        }
    }

    /**
     * 判断字符串是否包含在List列表
     *
     * @param list   字符串列表
     * @param string 要判断的字符串
     * @return true表示 @string 存在于字符串列表,false反之
     */
    public static boolean isIncludedString(List<String> list, String string) {
        if (string == null) {
            return false;
        }
        for (String listString : list) {
            if (string.contains(listString)) return true;
        }
        return false;
    }

    /**
     * 遍历在线玩家初始化数据
     * */
    public static void TraversePlayer() {
        for (Player player : Bukkit.getServer().getOnlinePlayers()) {
            tools.initPlayerData(player);
        }
    }

    /**
     * 初始化玩家数据
     *
     * @param player 需要初始化数据的玩家
     */
    public static void initPlayerData(Player player) {
        Main.PlayerDropLock.putIfAbsent(player, true);
        Main.PlayerDropLockTime.computeIfAbsent(player, k -> new Date());
        if(Main.PlayerPrivateDustbin.get(player) == null) {
            Main.PlayerPrivateDustbin.put(player, Bukkit.createInventory(player, Main.PrivateDustbinSize, Main.PrivateDustbinName));
        }
    }
    //  物品名称或ID转换为Material
    public static Material getMaterial(String value) {
        Material material = Material.getMaterial(value.toUpperCase());
        if (material != null && material != Material.AIR) {
            return material;
        }
        return Material.PAPER;
    }
}
